package player;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

import commons.Manager;
import commons.Media;
import commons.MetaData;

public class Player {

	public static enum OmxPlayerCommands {
		SHOW_INFO(0,"z"),
		DECREASE_SPEED(1,"1"),
		INCREASE_SPEED(2,"2"),
		PREVIOUS_AUDIO_STREAM(3,"j"),
		NEXT_AUDIO_STREAM(4,"k"),
		PREVIOUS_CHAPTER(5,"i"),
		NEXT_CHAPTER(6,"o"),
		PREVIOUS_SUBTITLE_STREAM(7,"n"),
		NEXT_SUBTITLE_STREAM(8,"m"),
		TOGGLE_SUBTITLES(9,"s"),
		SUBTITLE_DELAY_M250MS(10,"d"),
		SUBTITLE_DELAY_P250MS(11,"f"),
		EXIT(12,"q"),
		PAUSE_RESUME(13,"p"),
		DECREASE_VOLUME(14,"-"),
		INCREASE_VOLUME(15,"+"),
		SEEK_M30S(16,"[D"),		// left arrow
		SEEK_P30S(17,"[C"),		// right arrow
		SEEK_M600S(18,"[B"),	// down arrow
		SEEK_P600S(19,"[A");	// up arrow

		private int code;
		private String command;

		OmxPlayerCommands(int code, String command) {
			this.code = code;
			this.command = command;
		}

		public int getCode() {
			return this.code;
		}

		public String getCommand() {
			return this.command;
		}

		public static String getCommand(int code) {
			for (OmxPlayerCommands command : OmxPlayerCommands.values()) {
				if (command.code == code) return command.getCommand();
			}
			return null;
		}

		@Override
		public String toString() {
			return String.valueOf(this.code);
		}
	}

	private static final File WORKING_DIRECTORY = new File(System.getProperty("user.home") + File.separator + "airpi" + File.separator + "uploaded_files");
	private static final String PIPE = "/tmp/pipe.airpi";
	private static CheckPlaying check;

	/**
	 * Try to create a pipe and make it persistent
	 * @throws IOException When it's impossible to create the pipe
	 */
	private static synchronized void createPipe() throws IOException, InterruptedException {
		try {
			ProcessBuilder pb0 = new ProcessBuilder("/bin/sh", "-c","rm -f "+PIPE + " ; mkfifo "+PIPE +" ; tail -f /dev/null >"+PIPE);
			pb0.start();
			Thread.sleep(1000);
		} catch (IOException e) {
			System.out.println("Exception lors du create pipe");
			Runtime.getRuntime().exec("rm -f "+PIPE);
			Runtime.getRuntime().exec("mkfifo "+PIPE);
			Runtime.getRuntime().exec("tail -f /dev/null >"+PIPE);
		}
	}

	/**
	 * Play a file
	 * @param file The file to play
	 * @throws IOException When something wrong happened
	 */
	public static synchronized void playMedia(Manager parent, String path) {
		try {
			createPipe();
			System.out.println("Creation of OMXPLAYER process : " + path);
			ProcessBuilder pb5 = new ProcessBuilder("/bin/sh", "-c", "cat "+PIPE+" | (omxplayer -r \""+ path + "\" ; echo end ; xrefresh -d :0.0)");
			pb5.redirectErrorStream(true);
			java.lang.Process p = pb5.start();
			check = new CheckPlaying(parent, p);
			check.start();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public static synchronized void action(String s){
		try {
			ProcessBuilder pb4 = new ProcessBuilder("/bin/sh", "-c", "echo -n " +s+ " > "+PIPE);
			pb4.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Get meta data of a file
	 * @param path The path of the file to get meta data
	 * @param downloadFinished A boolean, true if the upload of the file is finished
	 */
	public static synchronized MetaData metaData(String path,boolean downloadFinished) {

		String artist="";
		String album="";
		String title="";
		String duration="";
		System.out.println("Metadata ||1");
		if(downloadFinished){
			try {
				System.out.println("Metadata ||2");
				ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", "omxplayer -i \""+ path + "\" ; echo end");
				System.out.println("Metadata ||3");
				pb.redirectErrorStream(true);
				System.out.println("Metadata ||4");
				java.lang.Process proc = pb.start();
				System.out.println("Metadata ||5");
				BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
				String line="";
				System.out.println("Metadata ||6");
				while(!(line=reader.readLine()).equals("end")){
					String[] table=line.split("\\s+");
					if(table.length>3){
						switch(table[1]){
						case "artist" :
							for(int i=3;i<table.length;i++){
								artist=artist+table[i]+" ";
							};
							break;
						case "album" :
							for(int i=3;i<table.length;i++){
								album=album+table[i]+" ";
							};
							break;
						case "title" :
							for(int i=3;i<table.length;i++){
								title=title+table[i]+" ";

							}
							break;
						case "Duration:" :
							duration=duration+table[2];
							String[] tab = duration.split(":");
							if(tab[0].equals("00")){
								duration=tab[1]+":"+tab[2].substring(0,2);
							}
							else{
								duration=tab[0]+":"+tab[1]+":"+tab[2].substring(0,2);
							}
							break;
						}
					}				
				}
				System.out.println("Metadata ||7");
				reader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		MetaData metadata = new MetaData(title,artist,album,duration);
		System.out.println("Metadata ||8");
		return metadata;
	}

	/**
	 * delete the thread CheckPlaying when the file is stopped or deleted
	 */
	public static void killCheckPlaying(){
		if(check.isAlive()){
			check.stopRunning();
			check = null;
			System.out.println("Thread CheckPlaying stopped");
		}
	}
}

